package logic

import (
	"context"
	"demo/internal/errorx"
	"demo/internal/svc"
	"demo/internal/types"
	"demo/model"
	"strconv"
	"strings"
	"time"

	"github.com/golang-jwt/jwt/v4"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/x/errors"
)



type LoginLogic struct{
	logx.Logger
	ctx context.Context
	svcCtx *svc.ServiceContext
	model model.UserModel
}

func NewLoginLogic(ctx context.Context,svcCtx *svc.ServiceContext)*LoginLogic{
	return &LoginLogic{
		Logger: logx.WithContext(ctx),
		ctx: ctx,
		svcCtx: svcCtx,
		model: model.NewUserModel(svcCtx.Orm),
	}
}

func (l *LoginLogic)Login(req *types.LoginReq, remoteAddr string)(resp *types.LoginResp,err error){
	// 校验基本入参
	if len(strings.TrimSpace(req.Username)) == 0 || len(strings.TrimSpace(req.Password)) == 0{
		// return nil,errors.New(1,"login params invail")
		return nil,errorx.ParamsError
	}
	// 校验DB密码 当前用户的id
	user,err := l.model.FindOneByUsername(l.ctx,req.Username)
	if err != nil {
		return nil,errors.New(1,"username error")
	}
	// 更新用户登录时的login_time and login_ip
	nowTime := time.Now()
	user.LastLoginTime = nowTime.Unix()
	user.LastLoginIp = remoteAddr
	l.model.Update(l.ctx,user)

	// 生成jwt 响应
	now := nowTime.Unix()
	accessExpire := l.svcCtx.Config.Auth.AccessExpire

	jwtToken,err := l.getJwtToken(l.svcCtx.Config.Auth.AccessSecret,now,accessExpire,strconv.FormatInt(user.Id,10))
	if err != nil{
		return nil,errors.New(1,"username or password error")
	}
	return &types.LoginResp{
		Id: user.Id,
		Name: req.Username,
		AccessToken: jwtToken,
		RefershAfter: now + accessExpire/2,
	},nil
}


func (l *LoginLogic)getJwtToken(secret string,newDate int64,accessExpire int64,payload string)(string,error){
	claims := make(jwt.MapClaims)
	claims["exp"] = newDate + accessExpire
	claims["iat"] = newDate
	claims["payload"] = payload

	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims
	return token.SignedString([]byte(secret))
}
